/*
 * Copyright (c) 2024. hallele, Inc All rights reserved.
 */

package cn.hallele.infrastructure.log.converter;

import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import cn.hallele.infrastructure.log.config.HalLogProperties;
import cn.hallele.infrastructure.log.util.SpringUtil;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

/**
 * 自定义converter做脱敏处理
 *
 * @author anle5
 * @since 2024/9/14 0:28
 */
public class HalConverter extends ClassicConverter {
    private HalLogProperties properties;

    /**
     * The convert method is responsible for extracting data from the event and
     * storing it for later use by the write method.
     *
     * @param event 日志事件
     */
    @Override
    public String convert(ILoggingEvent event) {
        this.properties = getProperties();

        if (this.properties == null) {
            return event.getFormattedMessage();
        }

        return doMask(event);
    }

    private String doMask(ILoggingEvent event) {
        if (!this.properties.isEnableMask()) {
            return event.getFormattedMessage();
        }

        String tempMsg = event.getFormattedMessage();
        boolean enableRegex = this.properties.isEnableRegex();
        List<HalLogProperties.MaskRule> maskRules = this.properties.getMaskRules();
        for (HalLogProperties.MaskRule maskRule : maskRules) {
            if (enableRegex && maskRule.getPattern() != null) {
                tempMsg = doRegexMask(tempMsg, maskRule);
            } else {
                tempMsg = doNormalMask(tempMsg, maskRule);
            }
        }
        return tempMsg;
    }

    private String doNormalMask(String tempMsg, HalLogProperties.MaskRule maskRule) {
        String maskKey = maskRule.getMaskKey();
        if (StringUtils.isBlank(maskKey)) {
            return tempMsg;
        }
        String[] keys = maskKey.split("\\|");
        if (keys.length != 2) {
            return tempMsg;
        }

        String indexes = keys[1];
        String[] index = indexes.split(",");
        if (index.length != 2 || !StringUtils.isNumeric(index[0].trim()) || !StringUtils.isNumeric(index[1].trim())) {
            return tempMsg;
        }

        int startIndex = Integer.parseInt(index[0].trim());
        int endIndex = Integer.parseInt(index[1].trim());
        if (startIndex > endIndex) {
            return tempMsg;
        }

        String keyName = keys[0].trim();
        String maskValue = maskRule.getMaskValue();
        int i = tempMsg.indexOf(keyName);
        while (i != -1) {
            // 避免索引越界
            startIndex = Math.max(startIndex, 0);
            endIndex = Math.min(endIndex, tempMsg.length() - i - keyName.length());
            String firstPart = tempMsg.substring(0, i + keyName.length() + startIndex - 1);
            String secondPart = tempMsg.substring(i + keyName.length() + endIndex);
            tempMsg = firstPart + maskValue + secondPart;
            i = tempMsg.indexOf(startIndex);
        }

        return tempMsg;
    }

    private String doRegexMask(String tempMsg, HalLogProperties.MaskRule maskRule) {
        return maskRule.getPattern().matcher(tempMsg).replaceAll(maskRule.getMaskValue());
    }

    private HalLogProperties getProperties() {
        HalLogProperties halLogProperties = SpringUtil.getBean(HalLogProperties.class);
        if (properties == null && halLogProperties != null) {
            return halLogProperties;
        }
        return this.properties;
    }
}
